package xin.yangshuai.mybatisgeneratorweb.service;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.templatemode.TemplateMode;
import xin.yangshuai.mybatisgeneratorweb.model.DataCodeInfo;
import xin.yangshuai.mybatisgeneratorweb.util.JdbcConnect;
import xin.yangshuai.mybatisgeneratorweb.util.ZipUtils;
import xin.yangshuai.mybatisgeneratorweb.vo.DataCodeDownloadVO;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * DataCodeInfoService
 *
 * @author shuai
 * @date 2021/7/29
 */
@Service
public class DataCodeInfoService {

    public static final String PATH_PREFIX = "/mbg-code-folder/";

    public static Map<Integer, DataCodeDownloadVO> map = new HashMap<>();

    public static int index = 0;

    public static List<DataCodeDownloadVO> list = new ArrayList<>();

    public String createGeneratorConfigFile(DataCodeInfo dataCodeInfo, Date date) throws Exception {

        SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
        resolver.setApplicationContext(new AnnotationConfigApplicationContext());
        resolver.setPrefix("/generatorConfig/");
        resolver.setSuffix(".xml");
        resolver.setCharacterEncoding("UTF-8");
        resolver.setTemplateMode(TemplateMode.XML);

        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(resolver);

        String dateFormat = new SimpleDateFormat("yyyyMMddHHmmss").format(date);
        String filePath = PATH_PREFIX + dateFormat + "/" + dataCodeInfo.getFolder();

        String host = dataCodeInfo.getHost();
        String port = dataCodeInfo.getPort();
        String userId = dataCodeInfo.getUserId();
        String password = dataCodeInfo.getPassword();
        String database = dataCodeInfo.getDatabase();
        String tablePrefix = dataCodeInfo.getTablePrefix();

        String url = "jdbc:mysql://" + host + ":" + port + "/" + database + "?serverTimezone=Asia/Shanghai";

        List<String> tableList = JdbcConnect.selectTable(url, userId, password, tablePrefix);

        if (CollectionUtils.isEmpty(tableList)) {
            throw new RuntimeException("table is zero");
        }

        Context context = new Context();
        context.setVariable("host", host);
        context.setVariable("port", port);
        context.setVariable("userId", userId);
        context.setVariable("password", password);
        context.setVariable("database", database);
        context.setVariable("tablePrefix", dataCodeInfo.getTablePrefix());
        context.setVariable("modelPackage", dataCodeInfo.getModelPackage());
        context.setVariable("mapperPackage", dataCodeInfo.getMapperPackage());
        context.setVariable("xmlPackage", dataCodeInfo.getXmlPackage());
        context.setVariable("filePath", filePath);
        context.setVariable("tableList", tableList);

        String xml = engine.process("generatorConfig-template", context);

        File file = new File(filePath);
        if (!file.isDirectory()) {
            file.mkdirs();
        }

        String xmlPath = PATH_PREFIX + dateFormat + ".xml";
        Writer writer = new FileWriter(new File(xmlPath));

        writer.write(xml);

        writer.flush();

        writer.close();

        return xmlPath;

    }

    public String createDataCode(DataCodeInfo dataCodeInfo) throws Exception {

        Date date = new Date();

        String xmlPath = createGeneratorConfigFile(dataCodeInfo, date);

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;

        File configFile = new File(xmlPath);

        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);


        String dateFormat = new SimpleDateFormat("yyyyMMddHHmmss").format(date);
        String filePath = PATH_PREFIX + dateFormat + "/" + dataCodeInfo.getFolder();

        String zipFilePath = ZipUtils.fileToZip(filePath);

        String createTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);

        index++;

        DataCodeDownloadVO dataCodeDownloadVO = new DataCodeDownloadVO(index, dataCodeInfo.getFolder(), createTime, zipFilePath);
        list.add(dataCodeDownloadVO);
        map.put(index, dataCodeDownloadVO);

        return "Hello World !";
    }

    public List<DataCodeDownloadVO> query() {
        return list;
    }

    public DataCodeDownloadVO selectById(Integer id) {
        return map.get(id);
    }
}
